if(!window["MUI"]) window["MUI"]={};

MUI.ComboBox = new Class({

    Implements: [Options, Events],
    
    options:{
	    writeable: false,
	    name: ['combobox', Math.ceil(Math.random()*100)].join(""),
	    animate:false,
	    resizable:false
    },
    
    initialize:function(data, options){
	this.setOptions(options);
	this.data = this.shownData = $pick(data, new Hash());
    },

    open:function(){
        var self = this;
	if(this.options.animate){
	    this.list.setStyles({"height":0, "display":"block"});
	    var effect = new Fx.Height(this.list, {
		onComplete:function(){
        	    self.opened = true;
		    if(self.options.resizable){
			self.resizeHandle.setStyle("display","block");
			self.positionResizer();
		    }
		    self.fireEvent("open");
		}
	    });
	    effect.custom(0, this.lastHeight);
	}else{
	    this.list.setStyle("display","block");
	    this.opened = true;
	    self.fireEvent("open");
	}
    },
    
    close: function(){
        this.lastHeight = this.list.offsetHeight;
	if(this.options.resizable){
	    this.resizeHandle.setStyle("display","none");
	}
	var self = this;
	if(this.options.animate){
	    var effect = new Fx.Height(this.list,{
		onComplete:function(){
		    self.list.setStyle("display","none");
		    self.opened = false;
		    self.fireEvent("close");
		}
	    });
	    effect.custom(this.lastHeight, 0);
	}else{
	    this.list.setStyle("display","none");
	    this.opened = false;
	    self.fireEvent("close");
	}
    },

    chosenClicked:function(){
	this[this.opened?"close":"open"]();
	
    },
    
    itemClicked:function(e){
	e = new Event(e);
	var target = $(e.target);
	this.chosen.setText(target.innerHTML);
	this.valueHolder.value = target.getProperty("realvalue");
	this.close();
    },
    
    _addItem:function(value, label){
	var self = this;
	var item = new Element("li", {realvalue:value, events:{
	    click: self.itemClicked.bind(self)
	}}).appendText(label).injectInside(this.list);
	return item;
    },
    
    makeResizable:function(){
	var self = this;
	this.selfEl.adopt(this.resizeHandle);
	this.list.makeResizable({
	    handle: self.resizeHandle,
	    xMin: self.chosen.offsetWidth,
	    yMin: self.list.firstChild.offsetHeight+30,
	    onComplete:function(){
		self.positionResizer();
	    }
	});
    },
    
    positionResizer:function(){
	this.resizeHandle.setStyle("top", (this.list.getTop()+this.list.offsetHeight-this.list.firstChild.offsetHeight-15)+"px");
	this.resizeHandle.setStyle("left", (this.list.offsetWidth-this.resizeHandle.offsetWidth-2)+"px");
	this.resizeHandle.setStyle("display","block");
    },
    
    chosenTyped:function(e){
	this.valueHolder.value = this.chosen.value;
	this.close();
    },
    
    render:function(){
	this.selfEl = new Element("div");
	this.selfEl.addClass("mui-combobox");
	if(this.data.getKeys().length){
	    this.chosen = new MUI[this.options.writeable?"Input":"Label"]();
	    this.chosen.setText(this.data.getValues()[0]);
	    this.chosen.addClass("mui-combobox-chosen-item");
	    this.chosen.addEvent("click", this.chosenClicked.bind(this));
	    this.chosen.addEvent("keyup", this.chosenTyped.bind(this));
	    this.list = new Element("ul");
	    this.list.setStyle("display","none");
	    this.shownData.each(function(value, key){
		this._addItem(key,value).injectInside(this.list);
	    }.bind(this));
	    
	    this.valueHolder = document.createElement("input");
	    this.valueHolder.type="hidden";
	    this.valueholder = $(this.valueHolder);
	    this.valueHolder.setProperty("name", this.options.name)
	    .setProperty("value", this.data.getKeys()[0]);
	    
	    this.selfEl.adopt(this.chosen).adopt(this.list).adopt(this.valueHolder);
	    if(this.options.resizable){
		this.resizeHandle = new Element("div").addClass("mui-combobox-resizer");
		this.makeResizable();
	    }
    	}
	return this.selfEl;
    },
    
    injectInside:function(el){
	el.appendChild(this.render());
	this.list.setStyle("visibility","hidden");
	this.list.setStyle("display","block");
	this.lastHeight = this.list.offsetHeight;
	this.list.setStyle("display","none");
	this.list.setStyle("visibility","visible");
    },
    
    set: function(container){
	container = $(container);
	var chosen = container.getFirst();
        
	if(chosen.get('tag')=='input'){
	    this.options.writeable=true;
	}
	var list = container.getElements("li");
	var $data = new Hash();
	list.forEach(function(item){
	    $data.set(item.getAttribute("realvalue"), item.innerHTML);
	});
	this.data = this.shownData = $data;
	console.log(this.data);

	this.options.name = container.getLast().getProperty("name");
	return this;
    }
    
    
});

MUI.CompleteAbleInput = new Class({

    Extends: MUI.ComboBox,
    
    initialize:function(data, options){
	this.parent(data, options);
	this.options.writeable = true;
    },
    
    chosenTyped:function(e){
	e = new Event(e);
	this.close();
	var val = this.chosen.getText().trim();
	if(val=='') return;
	this.valueHolder.value = val;
	this.shownData = new Hash();
	this.list = new Element("ul").replaces(this.list);
	this.data.each(function(value, key){
	    if(value.indexOf(val)==0 && value!=val){
		this.shownData.set(key,value);
		this._addItem(key,value).injectInside(this.list);
	    }
	}.bind(this));
	if(!this.list.hasChildNodes()){
	    this.close();
	}
	if(this.options.resizable) this.makeResizable();
    },
    
    chosenClicked:function(){
	this.close();
    },
    
    render:function(){
	this.parent();
	this.chosen.addEvent("keyup", this.chosenTyped.bind(this));
	return this.selfEl;
    }
    
    
});

MUI.RemoteCompleteAbleInput = new Class({

    Extends: MUI.CompleteAbleInput,
    
    chosenTyped:function(e){
	e = new Event(e);
	this.close();
	var val = this.chosen.getText();
	if(val=='') return;
	this.valueHolder.value = val;
	if(this.thread!=null){ $clear(this.thread); }
	this.thread = setTimeout(function(){
	    var self = this;
	    var url = [this.options.url, val].join("");
	    if(this.options.type == 'json'){
		new Request.JSON(url,{
		    onComplete:self.parseJSON.bind(self)
		}).get("");
	    }else{
		new Request(url, {
		    onComplete:function(responseText, responseXML){
			self.parseXML(responseXML);
		    }
		}).get("");
	    }
	}.bind(this), 1000);
    },
    
    parseXML:function(xml){
	var list = new Hash();
	$A(xml.documentElement.childNodes).each(function(node){
	    if(node.parentNode==xml.documentElement){
		list.set(node.nodeName, node.firstChild.data);
	    }
	});
	this._updateList(list);
    },
    
    parseJSON:function(jlist){
	var list = new Hash();
	jlist.each(function(item){
	    list.setValue(item["value"], item["label"]);
	});
	this._updateList(list);
    },
    
    _updateList:function(list){
	this.shownData = list;
	this.list = new Element("ul").replaces(this.list);
	this.shownData.each(function(key,value){
	    this._addItem(key,value).injectInside(this.list);
	}.bind(this));
	if(!this.list.hasChildNodes()){
	    this.close();
	}
	if(this.options.resizable) this.makeResizable();	
    }

});


Element.implement({
    makeAsComboBox:function(options){
	var combo = new MUI.ComboBox().setOptions(options).set(this);
	combo.render().replaces(this);
    },
    
    makeAsCompleteAble : function(options){
	var completable = new MUI.CompleteAbleInput().setOptions(options).set(this);
	//this.replaceWith(completable.render());
        completable.render().replaces(this);
    }
});
